package com.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.springframework.stereotype.Repository;

import com.entity.IssueEntity;
import com.entity.SubtasksEntity;

@Repository
public class IssueDaoImpl extends GenericDaoImpl<IssueEntity> implements IssueDao {

	public IssueEntity findIssueById(Integer id) {
		return getById(IssueEntity.class, id);
	}

	public List<IssueEntity> getAllIssues() {
		return getAll(IssueEntity.class);
	}

	public IssueEntity getIssueByFieldsId(int idFields) {
		String hql = "From IssueEntity as issue " + "where issue.fieldsEntity.idFields =:idFields";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setParameter("idFields", idFields);
		return (IssueEntity) query.uniqueResult();
	}

	public IssueEntity getIssueByUniqueId(String id) {
		String hql = "From IssueEntity where id =:id";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setParameter("id", id);
		return (IssueEntity) query.uniqueResult();
	}

	public IssueEntity getIssueByUniqueKey(String key) {
		String hql = "From IssueEntity where keyIssue =:key";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setParameter("key", key);
		return (IssueEntity) query.uniqueResult();
	}

	public IssueEntity getEagerIssueByUniqueKey(String key) {
		System.out.println(key);
		String hql = "From IssueEntity as issue "
				+ "left join fetch issue.fieldsEntity as fields "
				// TODO: ploblem with watchers
				+ "left join fetch issue.watchersEntities as watchers "
				// + "right join fetch watchers.userEntities as  userWatchers"
				+ "left join fetch fields.userEntityByIdAuthor as assignee " + "left join fetch fields.userEntityByIdReporter as reporter "
				+ "left join fetch fields.issueEntity as parent " + "left join fetch fields.resolutionEntity "
				+ "left join fetch fields.projectEntity as project " + "left join fetch project.projectCategoryEntity "
				+ "left join fetch fields.worklogEntity as worklog " + "left join fetch worklog.worklogsEntities "
				+ "left join fetch fields.priorityEntity " + "left join fetch fields.issueTypeEntity " + "left join fetch fields.statusEntity "
				+ "left join fetch fields.timetrackingEntity "
				+ "left join fetch fields.commentEntity as comment "
				+ "left join fetch comment.commentsEntities "
				// + "left join fetch issue.subtasksEntities as subtasks "
				// + "left join fetch subtasks.issueEntities "
				+ "left join fetch fields.issueEntities " + "left join fetch fields.attachmentEntities "
				+ "left join fetch fields.fixVersionsEntities " + "where issue.keyIssue =:key";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setParameter("key", key);

		IssueEntity resultEntity = (IssueEntity) query.uniqueResult();

		if (resultEntity != null) {
			resultEntity = addProperSubtasks(resultEntity);
			System.out.println(resultEntity);
		}
		return resultEntity;
	}

	public List<IssueEntity> getAllEagerIssueEntities() {
		String hql = "select distinct issue From IssueEntity as issue "
				+ "left join fetch issue.fieldsEntity as fields "
				// TODO: ploblem with watchers
				+ "left join fetch issue.watchersEntities as watchers "
				// + "right join fetch watchers.userEntities as  userWatchers"
				+ "left join fetch fields.userEntityByIdAuthor as assignee " + "left join fetch fields.userEntityByIdReporter as reporter "
				+ "left join fetch fields.issueEntity as parent " + "left join fetch fields.resolutionEntity "
				+ "left join fetch fields.projectEntity as project " + "left join fetch project.projectCategoryEntity "
				+ "left join fetch fields.worklogEntity as worklog " + "left join fetch worklog.worklogsEntities "
				+ "left join fetch fields.priorityEntity " + "left join fetch fields.issueTypeEntity " + "left join fetch fields.statusEntity "
				+ "left join fetch fields.timetrackingEntity "
				+ "left join fetch fields.commentEntity as comment "
				+ "left join fetch comment.commentsEntities "
				// + "left join fetch issue.subtasksEntities as subtasks "
				// + "left join fetch subtasks.issueEntities "
				+ "left join fetch fields.issueEntities " + "left join fetch fields.attachmentEntities "
				+ "left join fetch fields.fixVersionsEntities";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		List<IssueEntity> result = query.list();

		for (IssueEntity resultEntity : result)
			if (resultEntity != null) {
				resultEntity = addProperSubtasks(resultEntity);
				System.out.println(resultEntity);
			}
		return result;
	}

	public IssueEntity getEagerIssueByUniqueId(String id) {
		System.out.println("inside getEagerIssueByUniqueId" + id);
		String hql = "From IssueEntity as issue "
				+ "left join fetch issue.fieldsEntity as fields "
				// TODO: ploblem with watchers
				+ "left join fetch issue.watchersEntities as watchers "
				// + "right join fetch watchers.userEntities as  userWatchers"
				+ "left join fetch fields.userEntityByIdAuthor as assignee " + "left join fetch fields.userEntityByIdReporter as reporter "
				+ "left join fetch fields.issueEntity as parent " + "left join fetch fields.resolutionEntity "
				+ "left join fetch fields.projectEntity as project " + "left join fetch project.projectCategoryEntity "
				+ "left join fetch fields.worklogEntity as worklog " + "left join fetch worklog.worklogsEntities "
				+ "left join fetch fields.priorityEntity " + "left join fetch fields.issueTypeEntity " + "left join fetch fields.statusEntity "
				+ "left join fetch fields.timetrackingEntity "
				+ "left join fetch fields.commentEntity as comment "
				+ "left join fetch comment.commentsEntities "
				// + "left join fetch issue.subtasksEntities as subtasks "
				// + "left join fetch subtasks.issueEntities "
				+ "left join fetch fields.issueEntities " + "left join fetch fields.attachmentEntities "
				+ "left join fetch fields.fixVersionsEntities " + "where issue.id =:id ";
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setParameter("id", id);

		IssueEntity resultEntity = (IssueEntity) query.uniqueResult();

		if (resultEntity != null) {
			resultEntity = addProperSubtasks(resultEntity);
			System.out.println(resultEntity);
		}
		return resultEntity;
	}

	public IssueEntity addProperSubtasks(IssueEntity resultEntity) {
		if (resultEntity.getFieldsEntity().getIssueEntity() == null) {
			String sqlSelect = "SELECT b.issue_id_issue " + "FROM jiraexcel.subtasks as a,jiraexcel.subtasks_has_issue as b "
					+ "where a.id_fields=:id_fields " + "and a.id_subtasks=b.subtasks_id_subtasks";
			Query sqlquery = sessionFactory.getCurrentSession().createSQLQuery(sqlSelect);
			sqlquery.setParameter("id_fields", resultEntity.getFieldsEntity().getIdFields());
			List<Integer> subtasksId = (List<Integer>) sqlquery.list();
			System.out.println("subtasksId size: " + subtasksId.size());
			if (subtasksId.size() != 0) {
				String hqlQuery = "From IssueEntity where idIssue in (:subtasksId)";
				Query query = sessionFactory.getCurrentSession().createQuery(hqlQuery);
				query.setParameterList("subtasksId", subtasksId);

				List<IssueEntity> subtasksIssues = (List<IssueEntity>) query.list();
				System.out.println("subtasksIssues size: " + subtasksIssues.size());
				Set<IssueEntity> subtasksIssuesSet = new HashSet<IssueEntity>();
				for (IssueEntity iss : subtasksIssues) {
					subtasksIssuesSet.add(iss);
				}
				System.out.println("subtasksIssuesSet size: " + subtasksIssuesSet.size());
				Set<SubtasksEntity> subtasksEntities = new HashSet<SubtasksEntity>();
				SubtasksEntity subtask = new SubtasksEntity();
				subtask.setIssueEntities(subtasksIssuesSet);
				subtask.setFieldsEntity(resultEntity.getFieldsEntity());

				sqlSelect = "SELECT id_subtasks	" + "FROM jiraexcel.subtasks " + "where id_fields=:id_fields";
				sqlquery = sessionFactory.getCurrentSession().createSQLQuery(sqlSelect);
				sqlquery.setParameter("id_fields", resultEntity.getFieldsEntity().getIdFields());
				Integer parentIssueSubtaskId = (Integer) sqlquery.uniqueResult();

				subtask.setIdSubtasks(parentIssueSubtaskId);
				subtasksEntities.add(subtask);
				resultEntity.setSubtasksEntities(subtasksEntities);
				System.out.println(resultEntity.getSubtasksEntities().iterator().next().getIssueEntities().iterator().next().getKeyIssue());
				System.out.println("Reached end of addProperSubtasks ");
				return resultEntity;
			} else {
				resultEntity.setSubtasksEntities(new HashSet<SubtasksEntity>());
				System.out.println("Inside fake setSubtasksEntities");
				return resultEntity;

			}
		}
		return resultEntity;
	}

}
